package net.alche.fa.core.doing;
import net.alche.fa.core.model.Logic;
import net.alche.fa.core.model.FaValue;
import net.alche.fa.core.CodeLevel;
import net.alche.fa.core.SageStone;
import net.alche.fa.core.FaException;

//
// try
//
@FaAnnoDoing
public class TryDo extends AbstractDoing {

  @Override
  public boolean matched(String what, Logic g) {
    return "try".equals(what);
  }

  @Override
  public FaValue doing(Logic g, CodeLevel lvl, SageStone st) throws FaException {
    CodeLevel cl = lvl.instanceDeep();
    try {
      st.runCode(g.getChild(), cl);
    }
    catch (Exception ex) {
      lvl.exception = ex;
      lvl.isException = true;
      FaException fex;
      if (ex instanceof FaException) {
        fex = (FaException)ex;
      }
      else {
        fex = new FaException(ex);
        fex.setDebugFall(cl.debugFall);
        fex.setCodeLevel(cl);
      }
      Logic doLogic = null;
      for (Logic cc: g.getParam()) {
        if (this.compareException(cc.getObj(), fex)) {
          doLogic = cc;
          break;
        }
      }
      if (doLogic == null) {
        throw fex;
      }
      FaValue faValue = new FaValue(fex, FaValue._EXCEPTION);
      faValue.setObjType(doLogic.getData());
      st.putVar(doLogic.getData(), faValue);
      st.runCode(doLogic.getChild(), lvl);
      st.removeVar(doLogic.getData());
    }
    lvl.doChild = false;
    return lvl.returnObj;
  }

  // 
  public boolean compareException(String expName, FaException fex) {
    if (expName.equals("Exception")) {
      return true;
    }
    return false;
  }
}